/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "socket_utils.h"


#include "插座/通用插座.h"
#include "插座/字符插座.h"
#include "插座/C_数值插座.h"
#include "插座/C_矢量插座.h"
#include "插座/C_物体插座.h"
#include "插座/C_物理物体插座.h"
#include "插座/材质纹理插座.h"
#include "插座/几何插座.h"

#include "插座/list/list矢量插座.h"
#include "插座/list/list数值插座.h"
#include "插座/list/list物理物体插座.h"
#include "插座/list/list物体插座.h"
#include "插座/list/list元素插座.h"

using namespace std;





C_插座基类* f_su_创建节点后端插座(const u16string& socketName, E_值类型 type, void* mapdata, S_设备环境* ctx) {
	C_插座基类* socket = 0;

	switch (type) {
		//case e_插座Type_None:
		case e_Type_Bool:
			socket = new C_插座基类(socketName);
			break;
		case e_Type_LineText:
			break;
		case e_Type_F32:
			socket = new C_F32插座(socketName, (float32*)mapdata);
			break;
		case e_Type_F64:
			socket = new C_F64插座(socketName, (float64*)mapdata);
			break;
		case e_Type_I8: socket = new C_I8插座(socketName);
			break;
		case e_Type_I16:
			socket = new C_I32插座(socketName, (int32*)mapdata);
		case e_Type_I32:
			socket = new C_I32插座(socketName, (int32*)mapdata);
			break;
		case e_Type_UI32:
			socket = new C_UI32插座(socketName);
			break;
		case e_Type_I64: socket = new C_UI64插座(socketName);
			break;
		case e_Type_UI64: socket = new C_UI64插座(socketName);
			break;
		case e_Type_Vec2: socket = new C_Vec2插座(socketName);
			break;
		case e_Type_Vec3: socket = new C_Vec3插座(socketName);
			break;
		case e_Type_Vec4: socket = new C_Vec4插座(socketName);
			break;
		case e_Type_iVec2: socket = new C_iVec2插座(socketName);
			break;
		case e_Type_iVec3: socket = new C_iVec3插座(socketName);
			break;
		case e_Type_iVec4: socket = new C_iVec4插座(socketName);
			break;

		case e_Type_Shader: socket = new C_着色器插座(socketName);
			break;
		case e_Type_uVec2: socket = new C_uVec2插座(socketName);
			break;
		case e_Type_uVec3: socket = new C_uVec3插座(socketName);
			break;
		case e_Type_uVec4: socket = new C_uVec4插座(socketName);
			break;
		case e_Type_Mat2X2:
			break;
		case e_Type_Mat3X3: socket = new C_Mat3X3插座(socketName);
			break;
		case e_Type_Mat4X4: socket = new C_Matrix4X4插座(socketName);
			break;
		case e_Type_Object:
			socket = new C_物体插座(socketName);
			break;
		case e_Type_Mesh:
			socket = new C_网格插座(socketName);
			break;
		case e_Type_Mesh_1D:
			socket = new C_网格1D插座(socketName);
			break;
		//case e_插座Type_BlMesh:
		//	break;
		case e_插座Type_Line:
			break;
		case e_插座Type_Line_Array1D:
			socket = new C_线段插座_Array1D(socketName);
			break;

		case E_值类型::e_Type_多边形面: socket = new C_多边形面插座(socketName); break;
		//case E_值类型::e_Type_多边形面1D: socket = new C_多边形面插座_1D(socketName); break;

		case E_值类型::e_Type_多边形: socket = new C_多边形插座(socketName); break;
		case E_值类型::e_Type_多边形_1D: socket = new C_多边形插座_1D(socketName); break;

		case e_Type_骨骼:
			socket = new C_骨骼插座(socketName);
			break;

		case E_值类型::e_Type_骨架: socket = new C_骨架插座(socketName); break;
	
		

		case e_Type_Scene:
			//socket = new C_场景插座(socketName);
			break;
		case e_Type_集合:
			//socket = new C_集合插座(socketName);
			break;
		case e_Type_面顶点索引:
			//socket = new C_面顶点索引插座(socketName);
			break;
		case e_Type_多边形边: socket = new C_多边形边插座(socketName); break;
		case e_Type_多边形边1D: socket = new C_多边形边_1D插座(socketName); break;
		case e_Type_多边形元素: socket = new C_多边形元素插座(socketName); break;
		case e_Type_多边形元素1D: socket = new C_多边形元素_1D插座(socketName); break;
		case e_Type_车轮:
			//socket = new C_车轮属性插座(socketName);
			break;
		case e_Type_车辆:
			//socket = new C_车辆属性插座(socketName);
			break;
	
		case e_插座Type_物理体:
			socket = new C_物理体插座(socketName);
			break;
		case e_插座Type_物理体_Array1D:
			socket = new C_插座_物理体_1D(socketName);
			break;
		case e_插座Type_物理平面:
			break;
		case E_值类型::e_Type_颜色: socket = new C_颜色插座(socketName); break;
	
		case e_插座Type_引用数据:
			socket = new C_引用数据插座(socketName);
			break;


		case E_值类型::e_Type_Bool_1D:
			socket = new C_插座Bool_1D(socketName);
			break;

		case e_Type_F32_Array1D:
			socket = new C_Vector1D_F32插座(socketName);
			break;
		case e_Type_F32_1D: socket = new C_F32_1D插座(socketName);
			break;
		case e_Type_I8_1D: socket = new C_插座I8_Array1D(socketName);
			break;
		case e_Type_I32_1D:
			socket = new C_插座I32_1D(socketName);
			break;
		case e_插座Type_I32_Array2D:
			//socket = new C_插座I32_Array2D(socketName);
			break;
		case e_Type_UI32_1D: socket = new C_UI32插座_Array1D(socketName); break;
		case e_Type_UI32_2D: socket = new C_UI32_2D插座(socketName); break;
		case e_插座Type_UI32_Array2D:
			//socket = new C_UI32插座_Array1D(socketName);
			break;
		case e_Type_I64_Array1D:
			break;

		case e_Type_Vec2_Array1D: socket = new C_Vector1D_Vec2插座(socketName);
			break;
		case e_Type_Vec3_Array1D: socket = new C_Vector1D_Vec3插座(socketName);
			break;
		case e_Type_Vec2_1D: socket = new C_Vec2_1D插座(socketName);
			break;

		case e_Type_Vec3_1D: socket = new C_Vec3_1D插座(socketName); break;
		case e_Type_Vec3_2D: socket = new C_Vec3_2D插座(socketName); break;

		case e_Type_Vec4_1D: socket = new C_Vec4_1D插座(socketName); break;
		case e_Type_iVec4_1D: socket = new C_iVec4_1D插座(socketName); break;

		case e_Type_iVec3_1D: socket = new C_iVec3_1D插座(socketName); break;
		case e_Type_iVec3_2D: socket = new C_iVec3_2D插座(socketName); break;

		case e_Type_纹理: socket = new C_纹理插座(socketName, *ctx); break;
		case e_Type_纹理_1D: socket = new C_纹理1D插座(socketName); break;

		case e_Type_iVec2_1D: socket = new C_iVec2_1D插座(socketName);
			break;
		case e_Type_uVec2_1D: socket = new C_uVec2_1D插座(socketName);
			break;
		case e_Type_Array: socket = new C_数组插座(socketName);
			break;
		case e_插座Type_Mat2X2_Array1D:
			break;
		case e_插座Type_Mat3X3_Array1D:
			break;
		case e_Type_Mat4X4_Array1D:
			socket = new C_Array1D_Mat4X4插座(socketName);
			break;
		case e_Type_Mat4X4_1D: socket = new C_Mat4X4_1D插座(socketName); break;

		case E_值类型::e_插座Type_Vec球:
			//socket = new C_Vec球插座(socketName);
			break;
		case E_值类型::e_Type_VecSphere_1D:
			socket = new C_Vec球_1D_插座(socketName);
			break;


		case e_Type_Object_Array1D:
			socket = new C_插座_物体Array1D(socketName);
			break;
		case e_Type_Object_1D:
			socket = new C_物体插座_1D(socketName);
			break;

		case e_Type_材质: socket = new C_材质插座(socketName); break;

		case e_Type_材质1D: socket = new C_材质_1D插座(socketName); break;

		case e_Type_字体: socket = new C_字体插座(socketName); break;

		case E_值类型::e_Type_Str: socket = new C_字符串插座(socketName); break;
		case E_值类型::e_Type_LineStr1D: socket = new C_字符串数组插座(socketName); break;
	
		case E_值类型::e_Type_网格自定义属性:socket = new C_网格自定义属性插座(socketName); break;
		case E_值类型::e_Type_IK: socket = new C_IK插座(socketName); break;

		//	break;
		case e_插座Type_VectorParticle:
			break;
		case e_插座Type_VectorScene:
			break;
		case e_插座Type_物理材质_Array1D:
			//socket = new C_插座_物理材质Array1D(socketName);
			break;
		case E_值类型::e_Type_自定义结构:
			socket = new C_自定义结构插座(socketName);
			break;
	
	

		case e_Type_Bounding: socket = new C_包围盒插座(socketName); break;
		case e_Type_Bounding_1D: socket = new C_包围盒插座1D(socketName); break;
		
		case e_插座Type_车辆_Array1D:
			break;
		case e_插座Type_物理平面_Array1D:
			break;
		case e_插座Type_通用取:
			break;
		case E_值类型::e_Type_网格元素索引: socket = new C_插座模型元素索引(socketName); break;
		default:
			break;
	}


	if (!socket) {
		cout << "施工中" << endl;
	}

	return socket;
}

C_插座基类* f_su_切换后端插座类型(C_节点基类* node, E_插座方向 方向, int16 oldSocketLoc, E_值类型 newType, void* mapdata, bool 检查类型) {
	C_插座基类* socket = 0;
	C_插座基类* linkSocket = 0;
	if (方向 == E_插座方向::e_插座Type_输出) {
		socket = node->f_get输出插座(oldSocketLoc);
	}
	else {
		socket = node->f_get输入插座(oldSocketLoc);
	}
	if (socket->m_Type == newType && 检查类型) return socket;

	C_插座基类* newSocket = f_su_创建节点后端插座(socket->m_identifier, newType, mapdata, &node->m_Ctx);
	
	if (newSocket) {
		newSocket->f_set回写(socket->f_is回写());
		f_su_不同插座值拷贝(newSocket, socket);

		node->f_替换插座(newSocket, oldSocketLoc, 方向, 检查类型);
	}
	return newSocket;
}


void f_su_重构插座(E_插座方向 方向, C_节点基类* node, std::vector<S_类型名称>& socketType, void* mapdata) {
	uint32 多余插座数量 = 0;
	uint32 newNum = socketType.size();

	uint32 num;
	if (方向 == E_插座方向::e_插座Type_输入) {
		num = node->f_get输入插座数量() - 1;
	}
	else {
		num = node->f_get输出插座数量() - 1;
	}

	for (uint32 i = 0; i < newNum; ++i) {
		if (i < num) {
			auto* socket = f_su_切换后端插座类型(node, 方向, i+1, socketType[i].type, mapdata);
			//if (socket->on_UI更新) socket->on_UI更新(socket);
		}
		else {
			auto socket = f_su_创建节点后端插座(socketType[i].name, socketType[i].type, mapdata, &node->m_Ctx);
			node->f_add插座(socket, 方向);
		}
	}

	if (num > newNum) {
		num -= newNum;
		for (uint32 i = 0; i < num; ++i) {
			uint32 index = node->f_get输入插座数量() - 1;
			node->f_del插座(index, 方向);
		}
	}
}

void f_su_插座类型切换到连入的插座类型(C_节点基类* node, E_插座方向 dir, int16 oldSocketLoc, E_值类型 默认类型, const std::vector<E_值类型>& 指定类型) {
	switch (dir) {
		case E_插座方向::e_插座Type_输入: {
			auto* socket = node->f_get输入插座(oldSocketLoc);
			C_插座基类* 链接到的插座 = socket->f_getLinkOutSocket();

			if (链接到的插座) {
				
				if (指定类型.size()) {
					for (auto& t : 指定类型) {
						if (t == 链接到的插座->m_Type) {
							f_su_切换后端插座类型(node, dir, oldSocketLoc, 链接到的插座->m_Type);
							return;
						}
					}
				}
				else {
					f_su_切换后端插座类型(node, dir, oldSocketLoc, 链接到的插座->m_Type);
					return;
				}
			}
			
			f_su_切换后端插座类型(node, dir, oldSocketLoc, 默认类型);
			break;
		}
		case E_插座方向::e_插座Type_输出: {
			auto* socket = node->f_get输出插座(oldSocketLoc);
			auto 链接到的插座 = socket->f_get链接到的输入插座();
			if (链接到的插座.size()) {
				f_su_切换后端插座类型(node, dir, oldSocketLoc, 链接到的插座.front()->m_Type);
			}
			break;
		}
	}
}

E_值类型 f_su_插座类型切换到数组元素类型(C_节点基类* node, E_插座方向 dir, int16 loc, E_值类型 类型) {
	
	E_值类型 新类型;
	switch (类型) {
		case E_值类型::e_Type_多边形边1D: {
			新类型 = E_值类型::e_Type_多边形边; break;
		}
		case E_值类型::e_Type_多边形边: {
			新类型 = E_值类型::e_Type_uVec2; break;
		}
		case E_值类型::e_Type_F32_1D: {
			新类型 = E_值类型::e_Type_F32; break;
		}
		case E_值类型::e_Type_I8_1D: {
			新类型 = E_值类型::e_Type_I8; break;
		}
		case E_值类型::e_Type_I32_1D: {
			新类型 = E_值类型::e_Type_I32; break;
		}
		case E_值类型::e_Type_UI32_1D: {
			新类型 = E_值类型::e_Type_UI32; break;
		}

		case E_值类型::e_Type_Vec2_1D: 新类型 = E_值类型::e_Type_Vec2; break;
		case E_值类型::e_Type_Vec3_1D: 新类型 = E_值类型::e_Type_Vec3; break;
		case E_值类型::e_Type_Vec3_2D: 新类型 = E_值类型::e_Type_Vec3_1D; break;
		
		case E_值类型::e_Type_Vec4_1D: {
			新类型 = E_值类型::e_Type_Vec4; break;
		}
		case E_值类型::e_Type_iVec2_1D: {
			新类型 = E_值类型::e_Type_iVec2; break;
		}
		case E_值类型::e_Type_iVec3_1D: {
			新类型 = E_值类型::e_Type_iVec3; break;
		}
		case E_值类型::e_Type_iVec3_2D: {
			新类型 = E_值类型::e_Type_iVec3_1D; break;
		}
		case E_值类型::e_Type_UI32_2D: {
			新类型 = E_值类型::e_Type_UI32_1D; break;
		}
		case E_值类型::e_Type_Mat4X4_1D: {
			新类型 = E_值类型::e_Type_Mat4X4; break;
		}
		case E_值类型::e_Type_多边形元素: {
			新类型 = E_值类型::e_Type_多边形面; break;
		}
		case E_值类型::e_Type_多边形元素1D: {
			新类型 = E_值类型::e_Type_多边形元素; break;
		}
		case E_值类型::e_Type_Bounding_1D: {
			新类型 = E_值类型::e_Type_Bounding; break;
		}
		case E_值类型::e_Type_Object_1D: {
			新类型 = E_值类型::e_Type_Object; break;
		}
		case E_值类型::e_Type_纹理_1D: {
			新类型 = E_值类型::e_Type_纹理; break;
		}

		case E_值类型::e_Type_Str_1D:
		case E_值类型::e_Type_LineStr1D: {
			新类型 = E_值类型::e_Type_Str; break;
		}
		case E_值类型::e_Type_Array: 新类型 = E_值类型::e_Type_I8; break;
		default: {
			return E_值类型::e_Type_None;
		}
	}

	f_su_切换后端插座类型(node, dir, loc, 新类型);
	return 新类型;
}

void f_su_拷贝插座(C_节点基类* 源节点, C_节点基类* 目标节点, E_插座方向 源插座方向, E_插座方向 目标插座方向) {
	uint32 socketNum = 0;
	if (源插座方向 == E_插座方向::e_插座Type_输入) {
		socketNum = 源节点->f_get输入插座数量();

		for (uint32 j = 0; j < socketNum; ++j) {
			auto* p_socket = 源节点->f_get输入插座(j);
			if (j >= 目标节点->f_get输入插座数量()) {
				目标节点->f_add插座(f_su_创建节点后端插座(p_socket->m_identifier, p_socket->m_Type, nullptr, &目标节点->m_Ctx), 目标插座方向);
			}
			else {
				auto socket = f_su_切换后端插座类型(目标节点, 目标插座方向, j, p_socket->m_Type);
				socket->m_identifier = p_socket->m_identifier;
			}
		}
	}
	else {
		socketNum = 源节点->f_get输出插座数量();

		for (uint32 j = 0; j < socketNum; ++j) {
			auto* p_socket = 源节点->f_get输出插座(j);
			if (j >= 目标节点->f_get输出插座数量()) {
				目标节点->f_add插座(f_su_创建节点后端插座(p_socket->m_identifier, p_socket->m_Type, nullptr, &目标节点->m_Ctx), 目标插座方向);
			}
			else {
				auto socket = f_su_切换后端插座类型(目标节点, 目标插座方向, j, p_socket->m_Type);
				socket->m_identifier = p_socket->m_identifier;
			}
		}
	}
}

void f_su_交换插座位置(C_节点基类* 源节点, int32 s1, int32 s2, E_插座方向 插座方向) {
	
}

void f_su_数据拷贝到GPU(C_插座基类* socket)	{
	if (socket->m_GPU缓存.m_Buf == nullptr) return;
	
	switch (socket->m_Type) {
		case E_值类型::e_Type_F32:
			f_buf_F32_at(socket->m_GPU缓存) = DEF_F32插座数据(socket);
			break;
		case E_值类型::e_Type_I32:
			f_buf_I32_at(socket->m_GPU缓存) = DEF_I32插座数据(socket);
			break;
		case E_值类型::e_Type_UI32:
			f_buf_UI32_at(socket->m_GPU缓存, 0) = DEF_UI32插座数据(socket);
			break;
		case E_值类型::e_Type_Vec2:
			f_buf_Vec2_at(socket->m_GPU缓存) = DEF_Vec2插座数据(socket);
			break;
		case E_值类型::e_Type_Vec3:
			f_buf_Vec3_at(socket->m_GPU缓存) = DEF_Vec3插座数据(socket);
			break;
		case E_值类型::e_Type_Vec4:
			f_buf_Vec4_at(socket->m_GPU缓存) = DEF_Vec4插座数据(socket);
			break;

		case E_值类型::e_Type_iVec2:
			f_buf_iVec2_at(socket->m_GPU缓存) = DEF_iVec2插座数据(socket);
			break;
		case E_值类型::e_Type_iVec3:
			f_buf_iVec3_at(socket->m_GPU缓存) = DEF_iVec3插座数据(socket);
			break;
		//case E_值类型::e_Type_iVec4:
		//	f_buf_iVec4_at(socket->m_GPU缓存) = DEF_iVec4插座数据(socket);
		//	break;

		case E_值类型::e_Type_uVec2:
			f_buf_uVec2_at(socket->m_GPU缓存) = DEF_uVec2插座数据(socket);
			break;
		case E_值类型::e_Type_uVec3:
			f_buf_uVec3_at(socket->m_GPU缓存) = DEF_uVec3插座数据(socket);
			break;

		default:
			break;
	}
}




void f_su_不同插座值拷贝(C_插座基类* 目标插座, C_插座基类* 源插座) {
	switch (目标插座->m_Type) {
		case E_值类型::e_Type_F32: {
			switch (源插座->m_Type) {
				case E_值类型::e_Type_F32: {
					目标插座->f_setData(源插座->f_getData(0));
					break;
				}
				case E_值类型::e_Type_F32_1D: {
					const auto& v = DEF_F32插座_1D数据(源插座);
					if (v->count) {
						目标插座->f_setData(&v->ptr_userData[0]);
					}
					break;
				}
				default:
					break;
			}

			break;
		}
		case E_值类型::e_Type_F32_1D: {
			switch (源插座->m_Type) {
				case E_值类型::e_Type_F32: {
					const auto& v = DEF_F32插座数据(源插座);
					auto* s = DEF_F32插座_1D数据(目标插座);
					if (s->count) {
						s->ptr_userData[0] = v;
					}
					break;
				}
				case E_值类型::e_Type_F32_1D: {
					目标插座->f_setData(源插座->f_getData(0));
					break;
				}
				default:
					break;
			}

			break;
		}
		default:
			break;
	}
}




